#include once "Mcs51.bi"
constructor Mcs51()
    this.pc = &H0000
    EA = 0
    SP = &H07
    initRegGroup
end constructor

destructor Mcs51()

end destructor
sub Mcs51.initRegGroup()
  var state = (ram(regPSW) and &H1F) shr 3
  select case state
  case 0
    R0_ = g0R0
    R1_ = g0R1
    R2_ = g0R2
    R3_ = g0R3
    R4_ = g0R4
    R5_ = g0R5
    R6_ = g0R6
    R7_ = g0R7
  case 1
    R0_ = g1R0
    R1_ = g1R1
    R2_ = g1R2
    R3_ = g1R3
    R4_ = g1R4
    R5_ = g1R5
    R6_ = g1R6
    R7_ = g1R7
  case 2
    R0_ = g2R0
    R1_ = g2R1
    R2_ = g2R2
    R3_ = g2R3
    R4_ = g2R4
    R5_ = g2R5
    R6_ = g2R6
    R7_ = g2R7
  case 4
    R0_ = g3R0
    R1_ = g3R1
    R2_ = g3R2
    R3_ = g3R3
    R4_ = g3R4
    R5_ = g3R5
    R6_ = g3R6
    R7_ = g3R7
  end select

end sub
'运算器'
sub Mcs51.calc()
    cls
    dim as Instruction ins
    do
        if mode =1 then
          debug()
        end if
        'Locate 1,1
        print_info()
        insFetch

        'ins = insReg
        select case insReg_
          case ADD_A_R0
            add_a_rn(rn0)
          case ADD_A_R1
            add_a_rn(rn1)
          case ADD_A_R2
            add_a_rn(rn2)
          case ADD_A_R3
            add_a_rn(rn3)
          case ADD_A_R4
            add_a_rn(rn4)
          case ADD_A_R5
            add_A_rn(rn5)
          case ADD_A_R6
            add_a_rn(rn6)
          case ADD_A_R7
            add_a_rn(rn7)
          case ADD_A_DIRECT
            add_a_direct_()
          case ADD_A_ATR0
            add_a_atri(rn0)
          case ADD_A_ATR1
            add_a_atri(rn1)
          case ADD_A_DATA
            adda_data()
          case ADDC_A_R0
            addc_a_rn(rn0)
          case ADDC_A_R1
            addc_a_rn(rn1)
          case ADDC_A_R2
            addc_a_rn(rn2)
          case ADDC_A_R3
            addc_a_rn(rn3)
          case ADDC_A_R4
            addc_a_rn(rn4)
          case ADDC_A_R5
            addc_a_rn(rn5)
          case ADDC_A_R6
            addc_a_rn(rn6)
          case ADDC_A_R7
            addc_a_rn(rn7)
          case ADDC_A_DIRECT
            addc_a_direct_()
          case ADDC_A_ATR0
            addc_atri(rn0)
          case ADDC_A_ATR1
            addc_atri(rn1)
          case ADDC_A_DATA
            addc_a_data_()
          case SUBB_A_R0
            subb_a_rn(rn0)
          case SUBB_A_R1
            subb_a_rn(rn1)
          case SUBB_A_R2
            subb_a_rn(rn2)
          case SUBB_A_R3
            subb_a_rn(rn3)
          case SUBB_A_R4
            subb_a_rn(rn4)
          case SUBB_A_R5
            subb_a_rn(rn5)
          case SUBB_A_R6
            subb_a_rn(rn6)
          case SUBB_A_R7
            subb_a_rn(rn7)
          case SUBB_A_DIRECT
            subb_a_direct_()
          case SUBB_A_ATR0
              subb_a_atri(rn0)
          case SUBB_A_ATR1
              subb_a_atri(rn1)
          case SUBB_A_DATA
              subb_a_data_()
          case INC_A
              A = A +1
              isP
          case INC_R0
               R0 = R0 +1
          case INC_R1
              R1 = R1 +1
          case INC_R2
              R2 = R2 +1
          case INC_R3
              R3 = R3 +1
          case INC_R4
              R4 = R4+1
          case INC_R5
              R5 = R5 +1
          case INC_R6
              R6 = R6 +1
          case INC_R7
              R7 = R7 +1
          case INC_DIRECT
            inc_direct_()
          case INC_ATR0
            ramSet(R0,ramGet(R0)+1)
          case INC_ATR1
            ramSet(R1,ramGet(R1)+1)
          case INC_DPTR
            DPTR = DPTR +1
          case DEC_A
            A = A-1
            isP
          case DEC_R0
            R0 = R0 -1
          case DEC_R1
            R1 = R1 -1
          case DEC_R2
            R2 = R2 -1
          case DEC_R3
            R3 = R3 -1
          case DEC_R4
            R4 = R4 -1
          case DEC_R5
            R5 =R5 -1
          case DEC_R6
            R6 =R6 -1
          case DEC_R7
            R7 = R7 -1
          case DEC_DIRECT
            dec_direct_()
          case DEC_ATR0
            ramSet(R0,ramGet(R0)-1)
          case DEC_ATR1
            ramSet(R1,ramGet(R1)-1)
          case MUL_AB
            mul_ab_()
          case DIV_AB
            div_ab_()
          case DA_A
            da_a_()
          case ANL_A_R0
            A = A and R0
            isP
          case ANL_A_R1
            A = A and R1
            isP
          case ANL_A_R2
            A = A and R2
            isP
          case ANL_A_R3
            A =A and R3
            isP
          case ANL_A_R4
            A =A and R4
            isP
          case ANL_A_R5
            A = A and R5
            isP
          case ANL_A_R6
            A = A and R6
            isP
          case ANL_A_R7
            A= A and R7
            isP
          case ANL_A_DIRECT
            anl_a_direct_()
          case ANL_A_ATR0
            A = A and ramGet(R0)
            isP
          case ANL_A_ATR1
            A = A and ramGet(R1)
            isP
          case ANL_A_DATA
            'pc +=1
            A = A and rom(pc)
            isP
            pc +=1
          case ANL_DIRECT_A
            anl_direct_a_()
          case ANL_DIRECT_DATA
            anl_direct_data_()
          case ORL_A_R0
            A = A or R0
            isP
          case ORL_A_R1
            A = A or R1
            isP
          case ORL_A_R2
            A = A or R2
            isP
          case ORL_A_R3
            A =A or R3
            isP
          case ORL_A_R4
            A =A or R4
            isP
          case ORL_A_R5
            A = A or R5
            isP
          case ORL_A_R6
            A = A or R6
            isP
          case ORL_A_R7
            A = A or R7
            isP
          case ORL_A_DIRECT
            orl_a_direct_()
          case ORL_A_ATR0
            A = A or ramGet(R0)
            isP
          case ORL_A_ATR1
            A = A or ramGet(R1)
            isP
          case ORL_A_DIRECT
            orl_a_direct_()
          case ORL_A_ATR0
            A = A or ramGet(R0)
            isP
          case ORL_A_ATR1
            A = A or ramGet(R1)
            isP
          case ORL_A_DATA
            'pc +=1
            A = A or rom(pc)
            isP
            pc +=1
          case ORL_DIRECT_A
            orl_direct_a_()
          case ORL_DIRECT_DATA
            orl_direct_data_()
          case XRL_A_R0
            A = A xor R0
            isP
          case XRL_A_R1
            A = A xor R1
            isP
          case XRL_A_R2
            A = A xor R2
            isP
          case XRL_A_R3
            A =  A xor R3
            isP
          case XRL_A_R4
            A = A xor R4
            isP
          case XRL_A_R5
            A = A xor R5
            isP
          case XRL_A_R6
            A = A xor R6
            isP
          case XRL_A_R7
            A = A xor R7
            isP
          case XRL_A_DIRECT
            xrl_a_direct_()
          case XRL_A_ATR0
            A = A xor ramGet(R0)
            isP
          case XRL_A_ATR1
            A = A xor ramGet(R1)
            isP
          case XRL_A_DATA
            'pc +=1
            A = A xor romGet(pc)
            isP
            pc +=1
          case XRL_DIRECT_A
            'pc +=1
            A = ram(rom(pc)) xor A
            isP
            pc +=1
          case XRL_DIRECT_DATA
            xrl_direct_data_()
          case CLR_A
            A =0
          case CPL_A
            A = not A
          case RL_A
            rl_a_()
          case RLC_A
            rlc_a_()
          case RR_A
            rr_a_()
          case RRC_A
            rrc_a_()
          case SWAP_A
            swap_a_()
          case MOV_A_R0
            A = R0
            isP
          case MOV_A_R1
            A = R1
            isP
          case MOV_A_R2
            A = R2
            isP
          case MOV_A_R3
            A = R3
            isP
          case MOV_A_R4
            A = R4
            isP
          case MOV_A_R5
            A = R5
            isP
          case MOV_A_R6
            A = R6
            isP
          case MOV_A_R7
            A = R7
            isP
          case MOV_A_DIRECT
            'pc +=1
            A = ram(rom(pc))
            isP
            pc +=1
          case MOV_A_ATR0
            A = ram(R0)
            isP
          case MOV_A_ATR1
            A = ram(R1)
            isP
          case MOV_A_DATA

            A =rom(pc)
            pc +=1
            isP
          case MOV_R0_A
            R0 = A
          case MOV_R1_A
            R1 = A
          case MOV_R2_A
            R2 =A
          case MOV_R3_A
            R3 = A
          case MOV_R4_A
            R4 =A
          case MOV_R5_A
            R5 = A
          case MOV_R6_A
            R6 = A
          case MOV_R7_A
            R7 =A
          case MOV_R0_DIRECT

            R0 = ram(rom(pc))
            pc +=1
          case MOV_R1_DIRECT

            R1 = ram(rom(pc))
            pc + =1
          case MOV_R2_DIRECT

            R2 = ram(rom(pc))
            pc +=1
          case MOV_R3_DIRECT

            R3 =ram(rom(pc))
            pc +=1
          case MOV_R4_DIRECT

            R3 =ram(rom(pc))
            pc +=1
          case MOV_R4_DIRECT
            R4 =ram(rom(pc))
            pc +=1
          case MOV_R5_DIRECT

            R5 = ram(rom(pc))
            pc +=1
          case MOV_R6_DIRECT

            R6 = ram(rom(pc))
            pc +=1
          case MOV_R7_DIRECT
            R7 = ram(rom(pc))
            pc +=1
          case MOV_R0_DATA

            R0 = romGet(pc)
            pc += 1
          case MOV_R1_DATA

            R1 =romGet(pc)
            pc +=1
          case MOV_R2_DATA

            R2 =romGet(pc)
            pc +=1
          case MOV_R3_DATA

            R3 = romGet(pc)
            pc +=1
          case MOV_R4_DATA

            R4 =romGet(pc)
            pc +=1
          case MOV_R5_DATA

            R5 = romGet(pc)
            pc +=1
          case MOV_R6_DATA

            R6 =romGet(pc)
            pc +=1
          case MOV_R7_DATA

            R7 =romGet(pc)
            pc +=1
          case MOV_DIRECT_A

            ram(rom(pc)) = A
            pc +=1
          case MOV_DIRECT_R0
            ram(rom(pc)) =R0
            pc +=1
          case MOV_DIRECT_R1
            ram(rom(pc)) =R1
            pc +=1
          case MOV_DIRECT_R2
            ram(rom(pc)) =R2
            pc +=1
          case MOV_DIRECT_R3
            ram(rom(pc)) =R3
            pc +=1
          case MOV_DIRECT_R4
            ram(rom(pc)) =R4
            pc +=1
          case MOV_DIRECT_R5

            ram(rom(pc)) =R5
              pc +=1
          case MOV_DIRECT_R6

            ram(rom(pc)) =R6
            pc +=1
          case MOV_DIRECT_R7
            ram(rom(pc)) =R7
            pc +=1
          case MOV_DIRECT1_DIRECT2
            ram(rom(pc+1)) = ram(rom(pc))
            pc +=2
          case MOV_DIRECT_ATR0

            ram(rom(pc)) =ram(R0)
            pc +=1
          case MOV_DIRECT_ATR1

            ram(rom(pc)) = ram(R1)
            pc +=1
          case MOV_DIRECT_DATA

            ram(rom(pc)) = rom(pc+1)
            pc +=2
          case MOV_ATR0_A
            ramSet(R0,A)
          case MOV_ATR1_A
            ramSet(R1,A)
          case MOV_ATR0_DIRECT

            ram(R0) = ram(rom(pc))
            pc +=1
          case MOV_ATR1_DIRECT
            ram(R1) = ram(rom(pc))
            pc +=1
          case MOV_ATR0_DATA
            ram(R0) = rom(pc)
            pc +=1
          case MOV_ATR1_DATA
            ram(R1) = rom(pc)
            pc +=1
          case MOV_DPTR_DATA16

            ram(regDPH) = rom(pc)
            pc +=1
            ram(regDPL) = rom(pc)
            pc +=1
          case MOVC_A_ATADPTR
            A =rom(A + DPTR)
            isP
          case MOVC_A_ATAPC

            A =rom(A + pc)
            isP
            'pc +=1
          case MOVX_A_ATR0
            A = extRamGet(R0)
            isP
          case MOVX_A_ATR1
            A = extRamGet(R1)
            isP
          case MOVX_A_ATDPTR
            A = extRamGet(DPTR)
            isP
          case MOVX_ATR0_A
            extRamSet(R0,A)
          case MOVX_ATR1_A
            extRamSet(R1,A)
          case MOVX_DPTR_A
            extRamSet(DPTR,A)
          case PUSH_DIRECT
            push
          case POP_DIRECT
            pop
          case XCH_A_R0
            dim as dt tmp
            tmp =A
            A =R0
            R0 =A
            isP
          case XCH_A_R1
            dim as dt tmp
            tmp =A
            A =R1
            R1 =A

            isP
          case XCH_A_R2
            dim as dt tmp
            tmp =A
            A =R2
            R2 =A
            isP
          case XCH_A_R3
            dim as dt tmp
            tmp =A
            A =R3
            R3 =A
            isP
          case XCH_A_R4
            dim as dt tmp
            tmp =A
            A =R4
            R4 =A
            isP
          case XCH_A_R5
            dim as dt tmp
            tmp =A
            A =R5
            R5 =A
            isP
          case XCH_A_R6
            dim as dt tmp
            tmp =A
            A =R6
            R7 =A
            isP
          case XCH_A_R7
            dim as dt tmp
            tmp =A
            A =R7
            R7 =A
            isP
          case XCH_A_DIRECT

            dim as dt tmp =A
            A =ram(rom(pc))
            ram(rom(pc)) =tmp
            isP
            pc +=1
          case XCH_A_ATR0
            dim as dt tmp =A
            A =ramGet(R0)
            ramSet(R0,tmp)
            isP
          case XCH_A_ATR1
            dim as dt tmp =A
            A =ramGet(R1)
            ramSet(R1,tmp)
            isP
          case XCHD_A_ATR0
            dim as dt tmpA = A and &H0F
            dim as dt tmpri = R0 and &H0F
            dim as dt tmp =tmpA
            tmpA =tmpri
            tmpri =tmp
            A = A and &HF0
            R0 = R0 and &HF0
            A = A or tmpA
            R0 = R0 or tmpri
            isP
          case XCHD_A_ATR1
            dim as dt tmpA = A and &H0F
            dim as dt tmpri = ram(R1) and &H0F
            dim as dt tmp =tmpA
            tmpA =tmpri
            tmpri =tmp
            A = A and &HF0
            ram(R1) = ram(R1) and &HF0
            A = A or tmpA
            ram(R1) = ram(R1) or tmpri
            isP
          case CLR_C
            Cy =0
          case CLR_BIT
            bit_set(0)
          case SETB_C
            Cy =1
          case SETB_BIT
            bit_set(1)
          case CPL_C
            Cy = not Cy
          case CPL_BIT
            cpl_bit_()
          case ANL_C_BIT
            Cy = Cy and bit_state(rom(pc))
            pc +=1
          case ANL_C_BIT2
            Cy = Cy and (not bit_state(rom(pc)))
            pc +=1
          case  ORL_C_BIT
            Cy = Cy or bit_state(rom(pc))
            pc +=1
          case ORL_C_BIT2
            Cy = Cy or (not bit_state(rom(pc)))
            pc +=1
          case MOV_C_BIT
            'print bit_state(rom(pc))
            Cy = bit_state(rom(pc))
            pc +=1
          case MOV_BIT_C
            bit_set(rom(pc),Cy)
            pc +=1
          case ACALL_ADDR11_1
            acall_addr11(0)
          case ACALL_ADDR11_3
            acall_addr11(1)
          case ACALL_ADDR11_5
            acall_addr11(2)
          case ACALL_ADDR11_7
            acall_addr11(3)
          case ACALL_ADDR11_9
            acall_addr11(4)
          case ACALL_ADDR11_B
            acall_addr11(5)
          case ACALL_ADDR11_D
            acall_addr11(6)
          case ACALL_ADDR11_F
            acall_addr11(7)
          case LCALL_ADDR16
            lcall()
          case RET
            pc = 0
            'pc = cast(ushort,ramGet(SP)) shl 8
            pc = ram(SP) shl 8
            SP = SP -1
            'pc = pc or cast(ushort,ramGet(SP))
            pc = pc or ram(SP)
            SP =SP -1
          case RETI
            'pc = 0
            pc = cast(ushort,ramGet(SP)) shl 8
            SP = SP -1
            pc = pc or cast(ushort,ramGet(SP))
            SP =SP -1
          case AJMP_ADDR11_0
            ajmp(0)
          case AJMP_ADDR11_2
            ajmp(1)
          case AJMP_ADDR11_4
            ajmp(2)
          case AJMP_ADDR11_6
            ajmp(3)
          case AJMP_ADDR11_8
            ajmp(4)
          case AJMP_ADDR11_A
            ajmp(5)
          case AJMP_ADDR11_C
            ajmp(6)
          case AJMP_ADDR11_E
            ajmp(7)
          case LJMP_ADDR16
            ljmp()
          case SJMP_REL
            sjmp()
          case JMP_ATADPTR
            pc = ramGet(A + DPTR)
          case JZ_REL
            jz_rel_()
          case NJZ_REL
            njz_rel_()
          case JC_REL
            jc_rel_()
          case NJC_REL
            njc_rel_()
          case JB_BIT_REL
              jb_bit_rel_()
          case JNB_BIT_REL
            jnb_bit_rel_()
          case JBC_BIT_REL
            jbc_bit_rel_()
          case CJNE_A_DIRECT_REL
            cjne_a_direct_rel_()
          case CJNE_A_DATA_REL
            cjne_a_data_rel_()
          case CJNE_R0_DATA_REL
            cjne_rn_data_rel(rn0)
          case CJNE_R1_DATA_REL
            cjne_rn_data_rel(rn1)
          case CJNE_R2_DATA_REL
            cjne_rn_data_rel(rn2)
          case CJNE_R3_DATA_REL
            cjne_rn_data_rel(rn3)
          case CJNE_R4_DATA_REL
            cjne_rn_data_rel(rn4)
          case CJNE_R5_DATA_REL
            cjne_rn_data_rel(rn5)
          case CJNE_R6_DATA_REL
            cjne_rn_data_rel(rn6)
          case CJNE_R7_DATA_REL
            cjne_rn_data_rel(rn7)
          case CJNE_ATR0_DATA_REL
            cjne_ri_data_rel(rn0)
          case CJNE_ATR1_DATA_REL
            cjne_ri_data_rel(rn1)
          case DJNZ_R0_REL
            djnz_rn_rel(rn0)
          case DJNZ_R1_REL
            djnz_rn_rel(rn1)
          case DJNZ_R2_REL
            djnz_rn_rel(rn2)
          case DJNZ_R3_REL
            djnz_rn_rel(rn3)
          case DJNZ_R4_REL
            djnz_rn_rel(rn4)
          case DJNZ_R5_REL
            djnz_rn_rel(rn5)
          case DJNZ_R6_REL
            djnz_rn_rel(rn6)
          case DJNZ_R7_REL
            djnz_rn_rel(rn7)
          case DJNZ_DIRECT_REL
            djnz_direct_rel_()
          case NOP
            asm
              nop
            end asm
          case else
            print "unknown instruction"
        end select

      loop until inkey = chr(27)
end sub

sub Mcs51.djnz_direct_rel_()

  dim as dt direct = rom(pc)
  pc +=1
  dim as byte rel = rom(pc)
  ram(direct) =ram(direct) -1
  'ramSet(direct,ram(direct) -1)
  pc +=1
  if ram(direct) <> 0 then
    pc = pc +rel
  end if
end sub
sub Mcs51.djnz_rn_rel(rn as registerNumber)
  dim as dt rndata
  select case rn
  case rn0
   R0 = R0 -1
   rndata = R0
  case rn1
    R1 =  R1 -1
    rndata = R1
  case rn2
    R2 = R2 -1
    rndata = R2
  case rn3
    R3 = R3 -1
    rndata = R3
  case rn4
    R4 = R4 -1
    rndata = R4
  case rn5
    R5 = R5 -1
    rndata = R5
  case rn6
    R6 = R6 -1
    rndata = R6
  case rn7
    R7 =R7 -1
    rndata = R7
  end select
  dim as byte rel = rom(pc)
  if rndata <> 0  then
    pc = pc + rel
  end if
    pc +=1
end sub
sub Mcs51.cjne_ri_data_rel(ri as registerNumber)
  dim as dt ridata
  select case ri
  case rn0
    'ridata =ramGet(rn0)
    ridata =rn0
  case rn1
    'ridata =ramGet(rn1)
    ridata = rn1
  end select
  'pc +=1
  dim as dt dat =rom(pc)
  pc +=1
  dim as byte rel =rom(pc)
  'pc +=1
  if ridata <> dat then
    pc =pc +rel
  end if
  if ridata < dat then
    Cy =1
  end if
end sub
sub Mcs51.cjne_rn_data_rel(rn as registerNumber)
  dim as dt rndata
  select case rn
  case rn0
    rndata = R0
  case rn1
    rndata = R1
  case rn2
    rndata = R2
  case rn3
    rndata = R3
  case rn4
    rndata = R4
  case rn5
    rndata = R5
  case rn6
    rndata = R6
  case rn7
    rndata = R7
  end select
  'pc +=1
  dim as dt dat =romGet(pc)
  pc +=1
  dim as byte rel =romGet(pc)

  if rndata <> dat then
    pc =pc +rel
  end if
  if rndata < dat then
    Cy =1
  else'unsure
    Cy =0
  end if
pc +=1
end sub
sub Mcs51.cjne_a_data_rel_()
  dim as dt dat =romGet(pc)
  pc +=1
  dim as byte rel =romGet(pc)
  'pc +=1
  if A <> dat then
    pc =pc +rel
  end if
  if A < dat then
    Cy =1
  end if
  pc +=1
end sub

sub Mcs51.cjne_a_direct_rel_()
  dim as dt direct =rom(pc)
  pc +=1
  dim as byte rel =rom(pc)
  'pc +=1
  if A <> ram(direct) then
    pc =pc +rel
  end if
  if A < ram(pc) then
    Cy =1
  end if
  pc +=1
end sub

sub Mcs51.jbc_bit_rel_()
  dim as ubyte bit_addr = rom(pc)
  pc +=1
  dim as ubyte rel_addr = rom(pc)
  'pc +=1
  if bit_state(bit_addr) =1 then
    bit_set(bit_addr,0)
    pc = pc + rel_addr
  end if
  pc +=1
end sub

sub Mcs51.jnb_bit_rel_()

  dim as ubyte bit_addr = rom(pc)
  pc +=1
  dim as ubyte rel_addr = rom(pc)
  'pc +=1
  if bit_state(bit_addr) =0 then
    pc = pc + rel_addr
  end if
    pc +=1
end sub
sub Mcs51.jb_bit_rel_()
  dim as ubyte bit_addr = rom(pc)
  pc +=1
  dim as ubyte rel_addr = rom(pc)
  'pc +=1
  if bit_state(bit_addr) =1 then
    pc = pc + rel_addr
  end if
    pc +=1
end sub
sub Mcs51.njc_rel_()
  dim as byte rel =rom(pc)
  if Cy = 0 then
    pc = pc + rel
  end if
end sub
sub Mcs51.jc_rel_()
  dim as byte rel =rom(pc)

  if Cy =1 then
    pc = pc + rel
  end if
end sub

sub Mcs51.njz_rel_()
  dim as byte rel =rom(pc)

  if A <>0 then
    pc = pc + rel
  end if
end sub
sub Mcs51.jz_rel_()
  dim as byte rel =rom(pc)
  if A =0 then
    pc = pc + rel
  end if
end sub

sub Mcs51.sjmp()
  'pc += 1
  dim as byte rel = rom(pc)
  'print rel
  pc = pc + rel
  pc +=1
  'print pc
end sub

sub Mcs51.ljmp()
  'pc +=1
  dim as ushort addr16 = cast(ushort,rom(pc))
  pc +=1
  addr16 = addr16 or cast(ushort ,rom(pc) shl 8)
  pc = addr16
end sub

sub Mcs51.ajmp(n as ubyte)
  'pc +=1
  dim as ubyte addr = rom(pc)
  pc = pc and &HF800
  select case n
  case 0
    pc = pc and (&HFFF8 or addr)
  case 1
    pc = pc and (&HFFF9 or addr)
  case 2
    pc = pc and (&HFFFA or addr)
  case 3
    pc = pc and (&HFFFB or addr)
  case 4
    pc = pc and(&HFFFC or addr)
  case 5
    pc = pc and (&HFFFD or addr)
  case 6
    pc = pc and (&HFFFE or addr)
  case 7
    pc =pc and (&HFFFF or addr)
  end select
  pc +=1
end sub

sub Mcs51.lcall()
  'pc +=1
  dim as ushort addr16 = cast(ushort,rom(pc))
  pc +=1
  addr16 = addr16 or cast(ushort ,rom(pc) shl 8)
  SP =SP +1
  ramSet(SP,cast(dt,pc))
  SP = SP +1
  ramSet(SP,cast(dt,pc shr 8))
  pc  =addr16
end sub

sub Mcs51.acall_addr11(n as ubyte)
  dim as ushort addr = cast(ushort,rom(pc))
  pc =pc +2
  SP = SP +1
  ramSet(SP,cast(dt,pc))
  SP = SP +1
  ramSet(SP,cast(dt,pc shr 8))
  pc = pc and &HF800
  select case n
  case 0
    pc = pc and (&HFFF8 or addr)
  case 1
    pc = pc and (&HFFF9 or addr)
  case 2
    pc = pc and (&HFFFA or addr)
  case 3
    pc =pc and (&HFFFB or addr)
  case 4
    pc = pc and (&HFFFC or addr)
  case 5
    pc = pc and (&HFFFD or addr)
  case 6
    pc =pc and (&HFFFE or addr)
  case 7
    pc = pc and (&HFFFF or addr)
  end select

end sub
sub Mcs51.mov_bit_c_()

end sub
function Mcs51.bit_state(addr as ubyte) as byte
  if addr <= &H7F then
    return abs(bit(ramGet(addr),addr mod 8))
  else
    dim as ubyte tmpaddr = addr - (addr mod 8)
    return abs(bit(ram(tmpaddr),addr mod 8))
  end if

end function
sub Mcs51.cpl_bit_()
  '
  dim as ubyte bit_addr  =rom(pc)
  if bit_addr < = &H7F then
    if abs(bit(ramGet(bit_addr \8),bit_addr mod 8)) then
      ramSet(bit_addr \ 8,BCLR(ramGet(bit_addr \ 8),bit_addr mod 8))
    else
      ramSet(bit_addr \ 8,BSET( ramGet(bit_addr \ 8),bit_addr mod 8))
    end if
  else
    dim as ubyte tmpaddr = bit_addr -(bit_addr mod 8)
    if abs(bit(ramGet(tmpaddr),bit_addr mod 8))  then
      ramSet(tmpaddr,BCLR(ramGet(tmpaddr),(bit_addr mod 8)))
    else
      ramSet(tmpaddr,BSET(ramGet(tmpaddr),(bit_addr mod 8)))
    end if
  end if
  pc +=1
end sub
sub Mcs51.bit_set(addr as dt,val1 as dt)
if addr <= &H7F then

  if val1 =1 then
      ramSet(addr \ 8,BSET( ramGet(addr \ 8),addr mod 8))
  else
      ramSet(addr \ 8,BCLR(ramGet(addr \ 8),addr mod 8))
  end if
else
  dim as ubyte tmpaddr = addr -(addr mod 8)
  if val1 =1 then

    ramSet(tmpaddr,BSET(ramGet(tmpaddr),(addr mod 8)))
  else
    ramSet(tmpaddr,BCLR(ramGet(tmpaddr),(addr mod 8)))
  end if
end if

end sub
sub Mcs51.bit_set(val1 as dt)
  'pc +=1
  dim as ubyte addr = rom(pc)

  if addr <= &H7F then

    if val1 =1 then
        ramSet(addr \ 8,BSET( ramGet(addr \ 8),addr mod 8))
    else
        ramSet(addr \ 8,BCLR(ramGet(addr \ 8),addr mod 8))
    end if
  else
    dim as ubyte tmpaddr = addr -(addr mod 8)
    if val1 =1 then

      ramSet(tmpaddr,BSET(ramGet(tmpaddr),(addr mod 8)))
    else
      ramSet(tmpaddr,BCLR(ramGet(tmpaddr),(addr mod 8)))
    end if
  end if
  pc += 1
end sub
sub Mcs51.xchd_a_atri(ri as registerNumber)
end sub
sub Mcs51.pop()
  dim as dt direct_addr =rom(pc)
  'ramSet(direct_addr,ramGet(SP))
  ram(direct_addr) = ram(SP)
  SP =SP -1
  pc +=1
end sub
sub Mcs51.push()
  'pc +=1
  dim as dt direct_addr =rom(pc)
  SP = SP + 1
  'print hex(SP)
  'print ram(direct_addr)
  ram(SP) = ram(direct_addr)
  pc +=1
end sub

sub Mcs51.swap_a_()
  dim as dt lhalfbyte = (A and &H0F) shl 4
  dim as dt hhalfbyte = (A and &HF0) shr 4
  A = lhalfbyte  or hhalfbyte
end sub
sub Mcs51.rrc_a_()
  dim as dt lowbit =  abs(bit(A,0))
  A = A shr 1
  A = A or (Cy shl 8)
  Cy = lowbit
  isP
end sub
sub Mcs51.rr_a_()
  dim as dt lowbit =  abs(bit(A,0))
  A = A shr 1
  A = A or (lowbit shl 8)

end sub
sub Mcs51.rlc_a_()
  dim as dt hightbit =  abs(bit(A,7))
  A = A shl 1
  A = A or Cy
  Cy = hightbit
  isP
end sub
sub Mcs51.rl_a_()
  dim as dt hightbit =  abs(bit(A,7))
  A = A shl 1
  A = A or hightbit
end sub
sub Mcs51.xrl_direct_data_()
  dim as dt direct_addr = rom(pc)
  pc +=1
  dim as dt d = rom(pc)
  ramSet(direct_addr,ram(direct_addr) xor d)
  isP
  pc +=1
end sub
sub Mcs51.xrl_a_direct_()

  dim as dt direct_addr =rom(pc)
  A = A xor ram(direct_addr)
  isP
  pc +=1
end sub
sub Mcs51.orl_direct_data_()
  dim as dt direct_addr = rom(pc)
  pc +=1
  ramSet(direct_addr,ramGet(direct_addr) or romGet(pc))
  pc +=1
end sub
sub Mcs51.orl_direct_a_()

  dim as dt direct_addr =rom(pc)
  A = ramGet(direct_addr) or A
  pc +=1
end sub
sub Mcs51.orl_a_data_()

end sub
sub Mcs51.orl_a_direct_()

  dim as dt direct_addr =rom(pc)
  A = A or ramGet(direct_addr)
  isP
  pc +=1
end sub
sub Mcs51.anl_direct_data_()
  'pc += 1
  dim as dt direct_addr =rom(pc)
  pc  +=1
  dim as dt d =rom(pc)
  ramSet(direct_addr,ramGet(direct_addr) and d)
  pc +=1
end sub
sub Mcs51.anl_direct_a_()
    dim as dt direct_addr =rom(pc)
    ramSet(direct_addr,ramGet(direct_addr) and A)
    pc +=1
end sub
sub Mcs51.anl_a_direct_()
  'pc +=1
  dim as dt  direct_addr =rom(pc)
  A = A and ramGet(direct_addr)
  isP
  pc +=1
end sub
sub Mcs51.da_a_()
  dim as dt tmp  = A
  dim as dt tmpL = tmp and &H0F
  dim as dt tmpH = (tmp and &HF0) shr 4
  if (tmpL) > 9 or Ac =1 then
    tmpL = (tmpL + 6)
  end if
  if (tmpH > 9) or Cy =1 then
    tmpH =((tmpH +6) and &H0F)
  end if
  tmpH = tmpH shl 4
  A = tmpL + tmpH
end sub
sub Mcs51.div_ab_()
   dim as dt tmpa,tmpb
   tmpa = A
   tmpb = B
   A =tmpa  \tmpb
   B = tmpa mod tmpb

end sub
sub Mcs51.mul_ab_()
  dim as short res
  res = A * B
  A =  cast(dt,res )
  B = cast(dt,res shr 8)
  isP
  'isOV
end sub
sub Mcs51.dec_direct_()
    'pc +=1
    dim as dt direct_addr = rom(pc)
    ramSet(direct_addr,ramGet(direct_addr) -1)
    pc +=1
end sub
sub Mcs51.inc_direct_()
    'pc +=1
    dim as ushort direct = rom(pc)
    ramSet(direct ,ramGet(direct) +1)
    pc +=1
end sub
sub Mcs51.subb_a_data_()
  dim as dt d =romGet(pc)
  'isOV(A,-d - Cy)
  isAc(A,-d - Cy)
  isCy(A,-d - Cy)
  A = A - d - Cy
  isOV
  isP
  pc +=1
end sub
sub Mcs51.subb_a_atri(ri as registerNumber)
  dim as dt tmp
  select case ri
  case rn0
    tmp =ramGet(R0)
    A = A -tmp - Cy
  case rn1
    tmp =ramGet(R1)
    A = A - tmp - Cy
  end select

  'isOV(A,tmp)
  isCy(A,tmp)
  isAc(A,tmp)
  tmp = -tmp - Cy
  isOV
  isP
end sub
sub Mcs51.subb_a_direct_()
  'pc +=1
  dim as ushort direct_value  = ram(rom(pc))

  'isOV(A,-direct_value - Cy)
  isAc(A,-direct_value - Cy)
  isCy(A,-direct_value -Cy)
  A = A - direct_value - Cy
  isOV
  isP
  pc +=1
end sub
sub Mcs51.subb_a_rn(rn as registerNumber)
  dim as dt tmp
  select case rn
    case rn0
      A = A - R0 -Cy
      tmp = R0 +Cy
    case rn1
      A = A -R1 -Cy
      tmp = R1 +Cy
    case rn2
      A = A - R2 -Cy
      tmp = R2 +Cy
    case rn3
      A = A -R3 -Cy
      tmp = R3 +Cy
    case rn4
      A =A -R4 -Cy
      tmp =R4 +Cy
    case rn5
      A =A -R5 -Cy
      tmp =R5 + Cy
    case rn6
      A =A -R6 -Cy
      tmp = R6 + Cy
    case rn7
      A =A -R7 -Cy
      tmp = R7 +Cy
  end select
  isP
  'isOV(A+tmp,-tmp)
  isOV
  isAc(A+tmp,-tmp)
  isCy(A+tmp,-tmp)

end sub
sub Mcs51.addc_a_data_()
  '
  dim as dt d = romGet(pc)
  A = A +d +Cy
  isP
  'isOV(A,d + Cy)
  isOV
  isAc(A,d + Cy)
  isCy(A,d + Cy)
  pc +=1
end sub
sub Mcs51.addc_atri(rn as registerNumber)
  dim as dt tmp
  select case rn
  case rn0
    tmp =ramGet(rn0)
    A = A + tmp + Cy
  case rn1
    tmp =ramGet(rn1)
    A = A + tmp + Cy
  end select
  tmp = tmp +Cy
  isP
  'isOV(A -tmp,tmp)
  isOV
  isAc(A -tmp,tmp)
  isCy(A -tmp,tmp)
end sub
sub Mcs51.addc_a_direct_()

  dim as dt direct_value =ram(rom(pc))

  'isOV(A,direct_value + Cy)
  isAc(A,direct_value +Cy)
  isCy(A,direct_value + Cy)
  A =A + direct_value  +Cy
  isOV
  isP
  pc +=1
end sub
sub Mcs51.addc_a_rn(rn as registerNumber)
  dim as dt tmp

  select case rn
  case rn0
    A = A + R0 + Cy
    tmp = R0 +Cy
  case rn1
    A = A+R1 +Cy
    tmp = R1 + Cy
  case rn2
    A =A +R2 +Cy
    tmp = R1 +Cy
  case rn3
    A =A +R3 +Cy
    tmp =R3 + Cy
  case rn4
    A = A +R4 +Cy
    tmp =R4 +Cy
  case rn5
    A = A +R5 +Cy
    tmp = R5 + Cy
  case rn6
    A = A + R6 + Cy
    tmp = R6 + Cy
  case rn7
    A = A + R7 + Cy
    tmp =R7 +Cy
  end select
  isP
  'isOV(A-tmp,tmp)
  isOV
  isCy(A-tmp,tmp)
  isAc(A-tmp,tmp)
end sub
sub Mcs51.adda_data()
  dim as dt tmp =rom(pc)
  'isOV(A,tmp)
  isOV
  isCy(A,tmp)
  isAc(A,tmp)
  A = A +tmp
  isP
  pc +=1
end sub
sub Mcs51.add_a_atri(ri as registerNumber)
  dim as dt tmp
  select case ri
  case rn0
    tmp =ramGet(R0)
    A = A +tmp
  case rn1
    tmp =ramGet(R1)
    A = A + tmp
  end select
  isP
  'isOV(A-tmp,tmp)
  isOV
  isCy(A-tmp,tmp)
  isAc(A-tmp,tmp)
end sub
sub Mcs51.add_a_direct_()
    dim as dt tmp = ram(rom(pc))

    'isOV(A,tmp)
    isOV
    isCy(A,tmp)
    isAc(A,tmp)
    A = A + tmp
    isP
    pc +=1
end sub
sub Mcs51.add_a_rn(rn as registerNumber)

  dim as dt tmp
  select case rn
  case rn0
     A = A + R0
     tmp = R0
  case rn1
     A = A + R1
     tmp =R1
  case rn2
     A = A + R2
     tmp = R2
  case rn3
     A = A+ R3
     tmp =R3
  case rn4
    A = A + R4
    tmp =R4
  case rn5
    A = A + R5
    tmp =R5
  case rn6
    A = A+ R6
    tmp =R6
  case rn7
    A =A +R7
    tmp =R7
  end select
  'pc += 1 不能增加
  isP
  'isOV(A-tmp,tmp)
  isOV
  isAc(A-tmp,tmp)
  isCy(A-tmp,tmp)
end sub
'取指
sub Mcs51.insFetch()
    'insReg_ = ram(pc)
    insReg_ = rom(pc)
    pc + =1
end sub

function Mcs51.insReg() as ubyte
    return this.insReg_
end function

property Mcs51.R0() as dt
  return ram(R0_)
end property

property Mcs51.R0(val as dt)
    ram(R0_) =val
end property
property Mcs51.R1() as dt
  return ram(R1_)
end property

property Mcs51.R1(val as dt)
    ram(R1_) =val
end property

property Mcs51.R2() as dt
  return ram(R2_)
end property

property Mcs51.R2(val as dt)
    ram(R2_) =val
end property

property Mcs51.R3() as dt
  return ram(R3_)
end property

property Mcs51.R3(val as dt)
    ram(R3_) =val
end property

property Mcs51.R4() as dt
  return ram(R4_)
end property

property Mcs51.R4(val as dt)
    ram(R4_) =val
end property


property Mcs51.R5() as dt
  return ram(R5_)
end property

property Mcs51.R5(val as dt)
    ram(R5_) =val
end property

property Mcs51.R6() as dt
  return ram(R6_)
end property

property Mcs51.R6(val as dt)
    ram(R6_) =val
end property

property Mcs51.R7() as dt
  return ram(R7_)
end property

property Mcs51.R7(val as dt)
    ram(R7_) =val
end property


property Mcs51.A(val as dt)
  ram(regA) =val
end property
property Mcs51.A() as dt
  return ram(regA)
end property
property Mcs51.B(val as dt)
    ram(regB) =val
end property
property Mcs51.B() as dt
  return ram(regB)
end property
property Mcs51.SP( val as dt)
    'ramSet(regSP,val)
    ram(regSP) = val
end property
property Mcs51.SP() as dt
    'return ramGet(regSP)
    return ram(regSP)
end property
function Mcs51.ramGet(pc as ushort ) as dt
  return ram(pc)
end function
sub Mcs51.ramSet(pc as ushort,val as dt)
  ram(pc) =val
end sub

function Mcs51.romGet(pc as ushort ) as dt
  return rom(pc)
end function

sub Mcs51.romSet(pc as ushort,val as dt)
  rom(pc) = val
end sub

function Mcs51.extRamGet(pc as ushort ) as dt
  return extRam(pc)
end function

sub Mcs51.extRamSet(pc as ushort,val as dt)
  extRam(pc) = val
end sub
property Mcs51.PSW(val as dt)
  ram(regPSW) =val
end property
property Mcs51.PSW() as dt
  return ram(regPSW)
end property

property Mcs51.P(val as dt)
  if val =1 then
      ram(regPSW) = BSET(ram(regPSW),0)

  else
      ram (regPSW) =BCLR(ram(regPSW),0)
  end if
  'iif(val,bitset(ram(regPSW),0),bitreset(ram(regPSW),0))
end property
property Mcs51.P() as dt
  return abs(bit(ram(regPSW),0))
end property

property Mcs51.OV(val as dt)
if val =1 then
    ram(regPSW) = BSET(ram(regPSW),2)

else
    ram (regPSW) =BCLR(ram(regPSW),2)
end if
end property
property Mcs51.OV() as dt
  return abs(bit(ram(regPSW),2))
end property

property Mcs51.RS0(val as dt)
if val =1 then
    ram(regPSW) = BSET(ram(regPSW),3)

else
    ram (regPSW) =BCLR(ram(regPSW),3)
end if
end property
property Mcs51.RS0() as dt
  return abs(bit(ram(regPSW),3))
end property

property Mcs51.RS1(val as dt)
if val =1 then
    ram(regPSW) = BSET(ram(regPSW),4)

else
    ram (regPSW) =BCLR(ram(regPSW),4)
end if
end property
property Mcs51.RS1() as dt
  return abs(bit(ram(regPSW),4))
end property

property Mcs51.F0(val as dt)
if val =1 then
    ram(regPSW) = BSET(ram(regPSW),5)

else
    ram (regPSW) =BCLR(ram(regPSW),5)
end if
end property
property Mcs51.F0() as dt
  return abs(bit(ram(regPSW),5))
end property

property Mcs51.Ac(val as dt)
if val =1 then
    ram(regPSW) = BSET(ram(regPSW),6)

else
    ram (regPSW) =BCLR(ram(regPSW),6)
end if
end property
property Mcs51.Ac() as dt
  return abs(bit(ram(regPSW),6))
end property

property Mcs51.Cy(val as dt)
if val =1 then
    ram(regPSW) = BSET(ram(regPSW),7)
else
    ram (regPSW) =BCLR(ram(regPSW),7)
end if
end property
property Mcs51.Cy() as dt
  return abs(bit(ram(regPSW),7))
end property
property Mcs51.DPTR(val as ushort)
  'ramSet(regDPL , cast(dt,val and &H00FF))
  ram(regDPL) = cast(dt,val and &H00FF)
  'ramSet(regDPH , cast (dt,(val and &HFF00) shr 8))
  ram(regDPH) =  cast (dt,(val and &HFF00) shr 8)
end property
property Mcs51.DPTR() as ushort
    dim as ushort tmpL =cast(ushort,ram(regDPL))
    dim as ushort tmpH =cast(ushort,ram(regDPH)) shl 8
    dim as ushort res =tmpL or tmpH
    return  res
end property
sub Mcs51.isP()
  dim as dt tmp =A
  dim as byte res =0
  for i as typeof(tmp)= 0 to sizeof(A)*8-1
    if abs(Bit(tmp,i)) =1 then
      res +=1
    end if
  next
  if res mod 2 = 0 then
     P =0
  else
     P = 1
  end if

end sub

sub Mcs51.isOV(val1 as dt,val2 as dt)
  dim as ushort uval1,uval2
  uval1 =cast(ushort,val1)
  uval2 =cast(ushort,val2)
  if (uval1 + uval2 > &HFF) then
    OV =1
  else
    OV =0
  end if
end sub
sub Mcs51.isOV()
  OV = abs(bit(A,7)) xor abs(bit(A,6))
end sub
sub Mcs51.isCy(val1 as dt,val2 as dt)
  '';dim as byte sign =
  dim as ubyte uval1,uval2
  uval1 =cast(ubyte,val1)
  uval2 =cast(ubyte,val2)
  if (uval1 + uval2 > &HFF) then
    Cy =1
  else
    Cy =0
  end if

end sub

sub Mcs51.isAc(val1 as dt,val2 as dt)
  val1   = val1 and &H0F
  val2  = val2 and &H0F
  if val1 +val2 > &H0F then
    Ac=1
  else
    Ac =0
  end if
end sub
sub Mcs51.loadhex(byref filename as const string)
    dim as integer f
    f = freefile
    open filename for input as #f
    if Err > 0 then print "打开文件失败"
    dim as string  buf
    dim as integer datalen
    dim as integer addr_start
    dim as byte hextype
    dim as ubyte dat
    'dim shared as ubyte ins(0 to 64000-1)
    dim as integer base_addr = 0
    dim as integer ex_addr = 0
    while  not eof(f)
      input #f,buf
      if Mid(buf,1,1) <> ":" then
        print "文件内容有误"
      endif
      datalen = valhex(Mid(buf,2,2))
      addr_start = valhex(Mid(buf,4,4))
      hextype = valhex(Mid(buf,8,2))
      'print datalen,addr_start,hextype
      select case hextype
      case 0
        datarecord(mid(buf,10,datalen*2),base_addr+addr_start)
      case 1
        exit while
      case 2
        base_addr = valhex(Mid(buf,10,4)) shl 4
      case 3
      case 4
        base_addr = valhex(Mid(buf,10,4)) shl 16
      case 5
      end select
    wend
end sub

function Mcs51.valhex(byref s as  string) as integer
  dim as integer res =0
  dim as integer slen = len(s)
  dim as string tmpstr
  dim as integer tmp
  for i as integer = 0 to slen -1
    tmpstr= ucase(mid(s,slen-i,1))
    if asc(tmpstr) >= asc("A") then
      tmp = asc(tmpstr) -55
    else
      tmp = valint(tmpstr)
    end if
    res + = (16^i) * tmp
  next
function = res
end function
sub Mcs51.datarecord(byval buf as string,byval addr as integer)
  do
    rom(addr) = valhex(left(buf,2))
    addr + =1
    buf = mid(buf,3,len(buf)-2)
  loop until( len(buf) = 0)
end sub
function Mcs51.getPc() as ushort
  return pc
end function

property Mcs51.EA(val1 as dt)
  bit_set(&HAf,val1)
end property
property Mcs51.EA() as dt
  return bit_state(&HAF)
end property
sub Mcs51.print_info()
cls 2
print "R0:";hex(R0);" R1:";hex(R1);" R2:";hex(R2);" R3:";hex(R3);" R4:";hex(R4);" R5:";hex(R5);" R6:";hex(R6);" R7:";hex(R7)

print "A:";hex(A);" B:";hex(B);" SP:";hex(SP);" DPTR:";hex(DPTR);" pc: 0x";hex(getPc,4);"H PSW:";bin(PSW,8)
sleep 50,1
end sub
sub Mcs51.debug()
  dim as string key
  print "->"
  do
    key =inkey
    if  key = "n"  then
      exit do
    elseif key =chr(27) then
      end
    end if
    sleep 100,1
  loop
end sub
